<template>
  <transition :name="directionName">
    <slot></slot>
  </transition>
</template>

<script>
export default {
  name: "page-slide",
  props: {
    // 首页路由path
    indexPagePath: {
      type: String,
      default: "/",
    },
  },
  data() {
    return {
      directionName: "slide-right", // 页面切换方向：slide-left左滑前进，slide-right右滑后退,
      routeStack: [], // 存储路由栈
    };
  },
  watch: {
    $route(val) {
      this.handleRouteChange(val);
    },
  },
  created() {
    this.routeStack = this.getSessionRouteStack() || [
      { path: this.indexPagePath },
    ];
  },
  methods: {
    handleRouteChange(to) {
      console.log(to);
      const len = this.routeStack.length;
      const currentRoute = this.routeStack[len - 1];
      // 判断是否是刷新路由
      if (currentRoute.path !== to.path) {
        if (len === 1) {
          // 初次打开非首页路由，前进
          this.setPageForward(to);
        } else {
          // len > 1
          const lastRoute = this.routeStack[len - 2];
          if (lastRoute.path === to.path) {
            // 打开上一页路由，后退
            this.setPageBack(currentRoute);
          } else {
            if (to.path === this.indexPagePath) {
              // 中途打开首页，后退，重置路由栈
              this.setDirectionName("slide-right");
              this.resetRouteStack();
            } else {
              // 常规情况，前进
              this.setPageForward(to);
            }
          }
        }
      }
    },
    // 前进
    setPageForward(route) {
      this.setDirectionName("slide-left");
      this.pushRouteStack(route);
    },
    // 后退
    setPageBack() {
      this.setDirectionName("slide-right");
      this.popRouteStack();
    },
    // 设置页面方向
    setDirectionName(name) {
      this.directionName = name;
    },
    // 重置
    resetRouteStack() {
      this.routeStack = [{ path: this.indexPagePath }];
      this.setSessionRouteStack();
    },
    pushRouteStack(route) {
      const { path } = route;
      this.routeStack.push({ path });
      this.setSessionRouteStack();
    },
    popRouteStack() {
      this.routeStack.pop();
      this.setSessionRouteStack();
    },
    setSessionRouteStack() {
      try {
        sessionStorage.setItem("routeStack", JSON.stringify(this.routeStack));
      } catch (error) {
        console.warn("storage is not supported");
      }
    },
    getSessionRouteStack() {
      const str = sessionStorage.getItem("routeStack");
      if (!str) {
        return null;
      }
      let val = [];
      try {
        val = JSON.parse(str);
      } catch (error) {
        console.warn("parse routeStack wrong");
      }
      return val;
    },
  },
};
</script>

<style lang="scss" scoped>
$distanceX: 100%;

.slide-left-enter-active,
.slide-left-leave-active,
.slide-right-enter-active,
.slide-right-leave-active {
  position: absolute;
  width: 100%;
  transition: all 0.3s cubic-bezier(0.55, 0, 0.1, 1);
}

.slide-left-enter,
.slide-right-leave-active {
  opacity: 0;
  transform: translate($distanceX, 0);
}
.slide-left-leave-active,
.slide-right-enter {
  opacity: 0;
  transform: translate(-$distanceX, 0);
}
</style>
